class MyHashSet {

    private int    array_length = 128;
    private Node[] nodes        = new Node[array_length];

    public MyHashSet() {
    }

    public void add(int key) {
        int  hashCode = Integer.hashCode(key);
        int  index    = hashCode % array_length;
        Node node     = this.nodes[index];
        if (node == null) {
            node = new Node(key);
            this.nodes[index] = node;
        } else {
            node.addLast(key);
        }
    }

    public void remove(int key) {
        int  hashCode = Integer.hashCode(key);
        int  index    = hashCode % array_length;
        Node node     = this.nodes[index];
        if (node != null) {
            if (node.value == key) {
                this.nodes[index] = node.next;
            } else {
                removeNode(node, key);
            }
        }
    }

    private void removeNode(Node node, int key) {
        Node next = node.next;
        if (next != null) {
            if (next.value == key) {
                node.next = next.next;
            } else {
                removeNode(next, key);
            }
        }
    }


    public boolean contains(int key) {
        int  hashCode = Integer.hashCode(key);
        int  index    = hashCode % array_length;
        Node node     = this.nodes[index];
        return node != null && node.hasValue(key);
    }

    static class Node {
        Node next;
        int  value;

        Node(int value) {
            this.value = value;
        }

        // 将这个node添加到结尾最后一个
        void addLast(int key) {
            if (value == key) {
                return;
            }
            Node next = this.next;
            if (next == null) {
                this.next = new Node(key);
            } else {
                if (next.value != key) {
                    next.addLast(key);
                }
            }
        }

        boolean hasValue(int key) {
            return value == key || (next != null && next.hasValue(key));
        }
    }

}

